/*
 * $RCSfile: StringUtil.java,v $
 * $Revision: 1.1 $
 * $Date: 2009-01-29 $
 *
 * Copyright (C) 2005 Skin, Inc. All rights reserved.
 *
 * This software is the proprietary information of Skin, Inc.
 * Use is subject to license terms.
 */
package com.skin.webcat.util;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

/**
 * <p>Title: StringUtil</p>
 * <p>Description: </p>
 * <p>Copyright: Copyright (c) 2006</p>
 * @author xuesong.net
 * @version 1.0
 */
public class StringUtil {
    /**
     * empty string
     */
    public static final String EMPTY = "";
    private StringUtil(){}

    /**
     * @param list1
     * @param list2
     * @param token
     * @return List<String>
     */
    public static List<String> permutation(List<String> list1 , List<String> list2, String token) {
        StringBuilder buffer = new StringBuilder();
        List<String> result = new ArrayList<String>();

        for(String s1 : list1) {
            for(String s2 : list2) {
                buffer.setLength(0);
                buffer.append(s1);

                if(!isEmpty(token)) {
                    buffer.append(token);
                }

                buffer.append(s2);
                result.add(buffer.toString());
            }
        }

        return result;
    }

    /**
     * @param args
     * @return boolean
     */
    public static boolean isEmpty(String ... args) {
        if(args != null && args.length > 0) {
            for(String s : args) {
                if(s == null || s.trim().length() < 1 ) {
                    return true;
                }
            }

            return false;
        }

        return true;
    }

    /**
     * @param array
     * @param token
     * @return String
     */
    public static String join(char[] array, String token) {
        StringBuilder buffer = new StringBuilder();

        if(array != null && array.length > 0) {
            int length = array.length - 1;

            for(int i = 0; i < length; i++) {
                buffer.append(array[i]).append(token);
            }

            if(length < array.length) {
                buffer.append(array[length]);
            }
        }

        return buffer.toString();
    }

    /**
     * @param array
     * @param token
     * @return String
     */
    public static String join(boolean[] array, String token) {
        StringBuilder buffer = new StringBuilder();

        if(array != null && array.length > 0) {
            int length = array.length - 1;

            for(int i = 0; i < length; i++) {
                buffer.append(array[i]).append(token);
            }

            if(length < array.length) {
                buffer.append(array[length]);
            }
        }

        return buffer.toString();
    }

    /**
     * @param array
     * @param token
     * @return String
     */
    public static String join(byte[] array, String token) {
        StringBuilder buffer = new StringBuilder();

        if(array != null && array.length > 0) {
            int length = array.length - 1;

            for(int i = 0; i < length; i++) {
                buffer.append(array[i]).append(token);
            }

            if(length < array.length) {
                buffer.append(array[length]);
            }
        }

        return buffer.toString();
    }

    /**
     * @param array
     * @param token
     * @return String
     */
    public static String join(short[] array, String token) {
        StringBuilder buffer = new StringBuilder();

        if(array != null && array.length > 0) {
            int length = array.length - 1;

            for(int i = 0; i < length; i++) {
                buffer.append(array[i]).append(token);
            }

            if(length < array.length) {
                buffer.append(array[length]);
            }
        }

        return buffer.toString();
    }

    /**
     * @param array
     * @param token
     * @return String
     */
    public static String join(int[] array, String token) {
        StringBuilder buffer = new StringBuilder();

        if(array != null && array.length > 0) {
            int length = array.length - 1;

            for(int i = 0; i < length; i++) {
                buffer.append(array[i]).append(token);
            }

            if(length < array.length) {
                buffer.append(array[length]);
            }
        }

        return buffer.toString();
    }

    /**
     * @param array
     * @param token
     * @return String
     */
    public static String join(float[] array, String token) {
        StringBuilder buffer = new StringBuilder();

        if(array != null && array.length > 0) {
            int length = array.length - 1;

            for(int i = 0; i < length; i++) {
                buffer.append(array[i]).append(token);
            }

            if(length < array.length) {
                buffer.append(array[length]);
            }
        }

        return buffer.toString();
    }

    /**
     * @param array
     * @param token
     * @return String
     */
    public static String join(double[] array, String token) {
        StringBuilder buffer = new StringBuilder();

        if(array != null && array.length > 0) {
            int length = array.length - 1;

            for(int i = 0; i < length; i++) {
                buffer.append(array[i]).append(token);
            }

            if(length < array.length) {
                buffer.append(array[length]);
            }
        }

        return buffer.toString();
    }

    /**
     * @param array
     * @param token
     * @return String
     */
    public static String join(long[] array, String token) {
        StringBuilder buffer = new StringBuilder();

        if(array != null && array.length > 0) {
            int length = array.length - 1;

            for(int i = 0; i < length; i++) {
                buffer.append(array[i]).append(token);
            }

            if(length < array.length) {
                buffer.append(array[length]);
            }
        }

        return buffer.toString();
    }

    /**
     * @param array
     * @param token
     * @return String
     */
    public static String join(String[] array, String token) {
        StringBuilder buffer = new StringBuilder();

        if(array != null && array.length > 0) {
            int length = array.length - 1;

            for(int i = 0; i < length; i++) {
                buffer.append(array[i]).append(token);
            }

            if(length < array.length) {
                buffer.append(array[length]);
            }
        }
        return buffer.toString();
    }

    /**
     * @param text
     * @param length
     * @return String
     */
    public static String left(String text, int length) {
        if(text == null) {
            return EMPTY;
        }

        if(text.length() > length) {
            return text.substring(0, length);
        }
        else {
            return text;
        }
    }

    /**
     * @param text
     * @param length
     * @return String
     */
    public static String right(String text, int length) {
        if(text == null) {
            return EMPTY;
        }

        if(text.length() > length) {
            return text.substring(text.length() - length);
        }
        else {
            return text;
        }
    }

    /**
     * @param source
     * @return String
     */
    public static String ltrim(String source) {
        if(source == null) {
            return EMPTY;
        }

        for(int i = 0; i < source.length(); i++) {
            if(source.charAt(i) != ' ') {
                return source.substring(i);
            }
        }
        return source;
    }

    /**
     * @param source
     * @return String
     */
    public static String rtrim(String source) {
        if(source == null) {
            return EMPTY;
        }

        for(int i = source.length() - 1; i > -1; i--) {
            if(source.charAt(i) != ' ') {
                return source.substring(0, i + 1);
            }
        }

        return source;
    }

    /**
     * @param source
     * @param search
     * @param replacement
     * @return String
     */
    public static String replace(String source, String search, String replacement) {
        if(source == null) {
            return EMPTY;
        }

        if(search == null) {
            return source;
        }

        int s = 0;
        int e = 0;
        int d = search.length();
        String temp = source;
        StringBuilder buffer = new StringBuilder();

        while(true) {
            while(true) {
                e = temp.indexOf(search, s);

                if(e == -1) {
                    buffer.append(temp.substring(s));
                    break;
                }
                buffer.append(temp.substring(s, e)).append(replacement);
                s = e + d;
            }

            String result = buffer.toString();
            e = result.indexOf(search, 0);

            if(e > -1) {
                s = 0;
                temp = result;
                buffer.setLength(0);
            }
            else {
                break;
            }
        }

        return buffer.toString();
    }

    /**
     * @param source
     * @param delimiter
     * @return String
     */
    public String[] split(String source, String delimiter) {
        if(source == null || source.length() < 1) {
            return new String[0];
        }

        int s = 0;
        int e = 0;
        int d = delimiter.length();
        List<String> list = new ArrayList<String>();

        do {
            e = source.indexOf(delimiter, s);

            if(e == -1) {
                list.add(source.substring(s));
                break;
            }
            list.add(source.substring(s, e));
            s = e + d;
        }
        while(true);

        String[] result = new String[list.size()];
        list.toArray(result);

        return result;
    }

    /**
     * @param source
     * @param length
     * @param padding
     * @return String
     */
    public String substring(String source, int length, String padding) {
        if(source == null) {
            return EMPTY;
        }

        String s = source.trim();

        char c;
        int size = 0;
        int count = s.length();
        StringBuilder buffer = new StringBuilder();

        for(int i = 0; i < s.length(); i++) {
            c = s.charAt(i);

            if(c >= 0x0080) {
                size += 2;
                count++;
            }
            else {
                size++;
            }

            if(size > length) {
                if(c >= 0x4e00) {
                    size -= 2;
                }
                else {
                    size--;
                }

                break;
            }

            buffer.append(c);
        }

        if(size < count && padding != null) {
            buffer.append(padding);
        }

        return buffer.toString();
    }

    /**
     * @param source
     * @param token
     * @return List<String>
     */
    public static List<String> list(String source, String token) {
        List<String> list = new ArrayList<String>();
        StringTokenizer st = new StringTokenizer(source, token);

        while(st.hasMoreTokens()) {
            list.add(st.nextToken());
        }
        return list;
    }

    /**
     * @param source
     * @return String
     */
    public static String quote(String source) {
        StringBuilder buffer = new StringBuilder();
        buffer.append("\"");

        if(source != null) {
            char c;

            for(int i = 0, size = source.length(); i < size; i++) {
                c = source.charAt(i);

                switch (c) {
                    case '\\': {
                        buffer.append("\\\\"); break;
                    }
                    case '\'': {
                        buffer.append("\\\'"); break;
                    }
                    case '"': {
                        buffer.append("\\\""); break;
                    }
                    case '\r': {
                        buffer.append("\\r"); break;
                    }
                    case '\n': {
                        buffer.append("\\n"); break;
                    }
                    case '\t': {
                        buffer.append("\\t"); break;
                    }
                    case '\b': {
                        buffer.append("\\b"); break;
                    }
                    case '\f': {
                        buffer.append("\\f"); break;
                    }
                    default : {
                        buffer.append(c); break;
                    }
                }   
            }
        }
        buffer.append("\"");
        return buffer.toString();
    }

    /**
     * @param name
     * @return String
     */
    public static String camel(String name) {
        if(null == name || name.trim().length() < 1) {
            return "";
        }

        String[] subs = name.split("_");
        StringBuilder buffer = new StringBuilder();

        if(name.startsWith("_")) {
            buffer.append("_");
        }

        if(subs.length == 1) {
            String s = subs[0];

            if("ID".equals(s)) {
                buffer.append("Id");
            }
            else if(s.toUpperCase().equals(s)) {
                buffer.append(Character.toUpperCase(s.charAt(0)));
                buffer.append(s.substring(1).toLowerCase());
            }
            else {
                buffer.append(Character.toUpperCase(s.charAt(0))).append(s.substring(1));
            }
        }
        else {
            for(String s : subs) {
                if(s.length() > 0) {
                    if("ID".equals(s)) {
                        buffer.append(s);
                    }
                    else if(s.toUpperCase().equals(s)) {
                        buffer.append(Character.toUpperCase(s.charAt(0)));
                        buffer.append(s.substring(1).toLowerCase());
                    }
                    else {
                        buffer.append(Character.toUpperCase(s.charAt(0))).append(s.substring(1));
                    }
                }
            }
        }

        if(name.endsWith("_")) {
            buffer.append("_");
        }

        return buffer.toString();
    }

    /**
     * @param source
     * @param context
     * @return String
     */
    public static String replace(String source, Map<String, String> context) {
        char c;
        StringBuilder name = null;
        StringBuilder result = new StringBuilder();

        for(int i = 0; i < source.length(); i++) {
            c = source.charAt(i);

            if(c == '$' && i < source.length() - 1 && source.charAt(i + 1) == '{') {
                name = new StringBuilder();

                for(int j = i + 2; j < source.length(); j++) {
                    i = j;
                    c = source.charAt(j);

                    if(Character.isDigit(c) || Character.isLetter(c) || c == '_' || c == '-') {
                        name.append(c);
                    }
                    else {
                        String value = StringUtil.toString(context.get(name.toString()));

                        if(value != null) {
                            result.append(value);
                        }
                        else {
                            result.append("${").append(name).append("}");
                        }

                        if(c != '}') {
                            result.append(c);
                        }

                        break;
                    }
                }
            }
            else {
                result.append(c);
            }
        }

        return result.toString();
    }

    /**
     * @param object
     * @return String
     */
    public static String toString(Object object) {
        return toString(object, EMPTY);
    }

    /**
     * @param object
     * @param defaultValue
     * @return String
     */
    public static String toString(Object object, String defaultValue) {
        return (object != null ? object.toString() : defaultValue);
    }

    /**
     * @param s1
     * @param s2
     * @return boolean
     */
    public static boolean equals(String s1, String s2) {
        return (s1 != null && s1.equals(s2));
    }
}
